//
// Created by longyunbo on 6/23/21.
//

#include "ClassFileParser.h"
#include <stdlib.h>
DataTranslate* _dataTranslate;//工具类
#include <string>
#include <sstream>
#include <iostream>
#include<stdio.h>
#include<string.h>
using namespace std;

InstanceKlass* ClassFileParser::parseClassFile(FILE* fw){

    printf(" begin parseClassFile \n");
    InstanceKlass* instanceKlass = new InstanceKlass ;


    //通用
    char common_u1;
    short common_u2;
    int common_u4;
    long common_u8;


    //magic 魔术
    unsigned int magic;
    fread(&magic, sizeof(magic), 1, fw);
    magic = _dataTranslate->smallToBigEndU4(magic);
    instanceKlass->set_magic(magic);
    printf("魔术 magic %x \n",magic);

    //次版本
    unsigned short minor;
    fread(&minor,sizeof(minor),1,fw);
    minor = _dataTranslate->smallToBigEndU2(minor);
    instanceKlass->setminor(minor);
    printf(" 次版本 minor %d \n" , minor);

    //主版本
    unsigned short major;
    fread(&major,sizeof(major),1,fw);
    instanceKlass->setmajor(major);
    major = _dataTranslate->smallToBigEndU2(major);
    printf(" 主版本 minor %d \n" , major);

    //常量池大小 这个常量池大小就是逊啦!
    unsigned short constantPoolSize;
    fread(&constantPoolSize,sizeof(constantPoolSize),1,fw);
    constantPoolSize = _dataTranslate->smallToBigEndU2(constantPoolSize);
    ConstantPool* c = new ConstantPool;
    instanceKlass->set_constantPool(c);
    instanceKlass->get_constantPool()->set_length(constantPoolSize-1);
    printf(" 常量池大小 %d \n",instanceKlass->get_constantPool()->get_length());
    instanceKlass->get_constantPool()->initContainer(constantPoolSize);
    //开始解析常量池
    parseConstantPool(instanceKlass,fw);

    //解析类的访问权限
    unsigned short accessFlags;
    fread(&accessFlags,sizeof(short ),1,fw);
    accessFlags = _dataTranslate->smallToBigEndU2(accessFlags);
    instanceKlass->setaccessFlags(accessFlags);

    printf("类的访问权限 %d \n" , instanceKlass->getaccessFlags() );

    //当前类名下标
    unsigned short thisClassIndex;
    fread(&thisClassIndex,sizeof(short ),1,fw);
    thisClassIndex = _dataTranslate->smallToBigEndU2(thisClassIndex);
    instanceKlass->setthisClassIndex(thisClassIndex);
    printf("当前类名的下标 %d \n" , instanceKlass->getthisClassIndex() );
    //当前类名
    long thisClassName = instanceKlass->get_constantPool()->getClassName(instanceKlass->getthisClassIndex() );
    printf( "当前类名 %s \n" , thisClassName );
    instanceKlass->setthisClassName(thisClassName);

    //父类的下标
    unsigned short superClassIndex;
    fread(&superClassIndex,sizeof(short ),1,fw);
    superClassIndex = _dataTranslate->smallToBigEndU2(superClassIndex);
    instanceKlass->setsuperClassIndex(superClassIndex);
    printf("当前父类的下标 %d \n" , instanceKlass->getsuperClassIndex() );

    //父类的名字
    long superClassName = instanceKlass->get_constantPool()->getClassName(instanceKlass->getsuperClassIndex() );
    printf( "当前父类名 %s \n" , superClassName );
    instanceKlass->setsuperClassName(superClassName);


    //开始解析接口
    fread(&common_u2,sizeof(short ),1,fw);
    common_u2 = _dataTranslate->smallToBigEndU2(common_u2);
    instanceKlass ->setinterfaceLength(common_u2);
    //得到接口数量
    if( common_u2 > 0 ){
        //接口数量>0
        //开始解析
        parseInterface(instanceKlass,fw);
    }

//    InterfaceInfo* ii = instanceKlass->getInterfaceInfo().front();
//    long* lk=ii->getInterfaceName();
//    printf(" 得到 lk %s ",lk);


    //解析属性
    //得到属性长度
    fread(&common_u2,sizeof(short ),1,fw);
    common_u2 = _dataTranslate->smallToBigEndU2(common_u2);
    instanceKlass->setfileLength(common_u2);

    if( instanceKlass->getfileLength() > 0 ){

        parseFile(instanceKlass,fw);

    }
    //得到方法长度
    fread(&common_u2,sizeof(short ),1,fw);
    common_u2 = _dataTranslate->smallToBigEndU2(common_u2);
    instanceKlass->setmethodLength(common_u2);


//    printf(" method %d \n" , instanceKlass->getmethodLength() );
    //开始解析方法
    instanceKlass->initMethodInfo();
    parseMenthod(instanceKlass,fw);



    return instanceKlass;
}

//解析方法
void ClassFileParser::parseMenthod( InstanceKlass* in , FILE* fw ){

    short method_common_u2;
    int method_common_u4;
    ConstantPool* cp = in->get_constantPool();


    printf(" 开始解析方法 \n ");
    for( int i = 0 ; i < in->getmethodLength() ; i++ ){

        MethodInfo* mi = new MethodInfo;



        mi->setBelongKlass(in);
//        in->getMethodInfo()[i] =(*)mi;

        //access_flag
        fread(&method_common_u2,sizeof(short),1,fw);
        method_common_u2 = _dataTranslate->smallToBigEndU2(method_common_u2);

        AccessFlags* af = new AccessFlags(method_common_u2);
        mi->setAccessFlag(af);


        //name_index
        fread(&method_common_u2,sizeof(short),1,fw);
        method_common_u2 = _dataTranslate->smallToBigEndU2(method_common_u2);
        mi->setnameIndex(method_common_u2);

        //descriptor_index
        fread(&method_common_u2,sizeof(short),1,fw);
        method_common_u2 = _dataTranslate->smallToBigEndU2(method_common_u2);
        mi->setdescriptorIndex(method_common_u2);

        //attribute_info
        fread(&method_common_u2,sizeof(short),1,fw);
        method_common_u2 = _dataTranslate->smallToBigEndU2(method_common_u2);

        mi->setattributesCount(method_common_u2);

        mi->initAttributeContainer();
        printf(" \t 第 %d 个方法 access_flag: %d  name_index: %d  descriptor_index : %s  attribute count %d \n" , i+1 , (int)mi->getAccessFlag()->getFlag() , mi->getnameIndex()
               , in->get_constantPool()->get_item(mi->getdescriptorIndex()) , mi->getattributesCount() );

        //解析方法属性
        if( 1 != mi->getattributesCount() ){
            printf(" 方法属性不止一个 \n");
            exit(-1);
        }
//        printf( " 解析方法属性 \n" );
        for( int j = 0 ; j < mi->getattributesCount() ; j++ ){
//

            CodeAttributeInfo* codeAttributeInfo = new CodeAttributeInfo;

            CodeAttributeInfo* codeAttribute = mi->getCodeAttributeInfo();


            //codeAttributeInfo.
            //attribute_name_index u2
            fread(&method_common_u2,sizeof(short),1,fw);
            method_common_u2 = _dataTranslate->smallToBigEndU2(method_common_u2);
            codeAttributeInfo->set_attributeNameIndex((int*)method_common_u2);

            //attribute_length u4
            fread(&method_common_u4,sizeof(int),1,fw);
            method_common_u4 = _dataTranslate->smallToBigEndU4(method_common_u4);
            codeAttributeInfo->set_attributeLength( (int*)method_common_u4 );

            //max_stack u2
            fread(&method_common_u2,sizeof(short),1,fw);
            method_common_u2 = _dataTranslate->smallToBigEndU2(method_common_u2);
            codeAttributeInfo->set_maxStack((int*)method_common_u2);

            //max_locals u2
            fread(&method_common_u2,sizeof(short),1,fw);
            method_common_u2 = _dataTranslate->smallToBigEndU2(method_common_u2);
            codeAttributeInfo->set_maxlocals((int*)method_common_u2);

            //code length u4
            fread(&method_common_u4,sizeof(int),1,fw);
            method_common_u4 = _dataTranslate->smallToBigEndU4(method_common_u4);



            codeAttributeInfo->set_codeLength(method_common_u4);

            //code
            BytecodeStream* bs = new BytecodeStream(mi,codeAttributeInfo) ;
//            printf(b)
            codeAttributeInfo->setBytecodeStream(bs);
            fread(bs->get_codes(), bs->getLength() * sizeof(char),1,fw);

            printf(" \t\t 第 %d 个属性 access flag为:%d  name Index %d  statck:%d  locals %d   code len:%d  \n" , j+1 , mi->getAccessFlag()->getFlag() ,  codeAttributeInfo->get_attributeNameIndex()
            , codeAttributeInfo->get_maxStack() , codeAttributeInfo->get_maxlocals() , codeAttributeInfo->get_codeLength() );


            //exception_table_length u2
            fread(&method_common_u2,sizeof(short),1,fw);
            method_common_u2 = _dataTranslate->smallToBigEndU2(method_common_u2);

            codeAttributeInfo->set_exceptionTableLength((int*)method_common_u2);

            //attribute count
            fread(&method_common_u2,sizeof(short),1,fw);
            method_common_u2 = _dataTranslate->smallToBigEndU2(method_common_u2);

            codeAttributeInfo->set_attributesCount((int*)method_common_u2);

            for( int p = 0; p < (long) codeAttributeInfo->get_attributesCount() ; p++ ){
                //lineNumberTable / localVariableTable
                fread(&method_common_u2,sizeof(short),1,fw);
                method_common_u2 = _dataTranslate->smallToBigEndU2(method_common_u2);
                char* l = reinterpret_cast<char *>(cp->get_item(method_common_u2));
                if(strcmp(l, "LineNumberTable") == 0){
                    //解析LineNumberTable
                    parseLineNumberTable(in,fw,codeAttributeInfo,method_common_u2);
                }else{//LocalVariableTable
                    parseLocalVariableTable(in,fw,codeAttributeInfo,method_common_u2);
                }
            }
            codeAttribute[j] =*(codeAttributeInfo) ;
        };


        in->setMethodInfo(mi,i);
    }

}
void ClassFileParser::parseLocalVariableTable(InstanceKlass* in , FILE* fw , CodeAttributeInfo* codeAttributeInfo , short attribute ){


    short LocalVariableTable_u2;
    int LocalVariableTable_u4;

    LocalVariableTable* lvt = new LocalVariableTable;

    //attribute_name_index
    fread(&LocalVariableTable_u2,sizeof(short),1,fw);
    lvt->set_attrNameIndex((int*)attribute);

    //att_length
    fread(&LocalVariableTable_u4,sizeof(short),1,fw);
    LocalVariableTable_u4 = _dataTranslate->smallToBigEndU2(LocalVariableTable_u4);
    lvt->set_attrLength((int*)LocalVariableTable_u4);

    //table_length
    fread(&LocalVariableTable_u2,sizeof(short),1,fw);
    LocalVariableTable_u2 = _dataTranslate->smallToBigEndU2(LocalVariableTable_u2);
    lvt->set_tableLength((int*)LocalVariableTable_u2);

    lvt->initTable();

    printf("\t\t\t LocalVariableTable attribute_name_index %d  att_length %d table_length %d \n "
           , lvt->get_attributeNameIndex() , lvt->get_attrLength() , lvt->get_tablelength() );

    if( 0 == lvt->get_tablelength() ){
        return;
    }

    //table
    for( int i = 0 ; i < (long)lvt->get_tablelength() ; i++ ){

        LocalVariableTableItem* lvti = new LocalVariableTableItem;

        //start_Pc; u2
        fread(&LocalVariableTable_u2,sizeof(short),1,fw);
        LocalVariableTable_u2 = _dataTranslate->smallToBigEndU2(LocalVariableTable_u2);
        lvti->setStartPc((short*)LocalVariableTable_u2);

        //length; u2
        fread(&LocalVariableTable_u2,sizeof(short),1,fw);
        LocalVariableTable_u2 = _dataTranslate->smallToBigEndU2(LocalVariableTable_u2);
        lvti->setlength((short*)LocalVariableTable_u2);

        //name_index; u2
        fread(&LocalVariableTable_u2,sizeof(short),1,fw);
        LocalVariableTable_u2 = _dataTranslate->smallToBigEndU2(LocalVariableTable_u2);
        lvti->setnameIndex((short*)LocalVariableTable_u2);

        //descriptor_index; u2
        fread(&LocalVariableTable_u2,sizeof(short),1,fw);
        LocalVariableTable_u2 = _dataTranslate->smallToBigEndU2(LocalVariableTable_u2);
        lvti->setdescriptor_index((short*)LocalVariableTable_u2);

        //index; u2
        fread(&LocalVariableTable_u2,sizeof(short),1,fw);
        LocalVariableTable_u2 = _dataTranslate->smallToBigEndU2(LocalVariableTable_u2);
        lvti->setindex((short*)LocalVariableTable_u2);
        lvt->get_item()[i] = *lvti;
        printf(" \t\t\t\t 第 %d 个属性 startPc %d length %d name_index %d descriptor_index %d index %d \n" , i + 1 , lvt->get_item()[i].getStartPc()
                , lvt->get_item()[i].getlength() , lvt->get_item()[i].getnameIndex()
                , lvt->get_item()[i].getdescriptor_index(), lvt->get_item()[i].getindex());

    }

};


void ClassFileParser::parseLineNumberTable(InstanceKlass* in , FILE* fw , CodeAttributeInfo* codeAttributeInfo , short attribute ){

    short lineNumberTable_u2;
    int lineNumberTable_u4;

    long l = in->get_constantPool()->get_item(attribute);

    LineNumberTable* lineNumberTable = new LineNumberTable ;

    codeAttributeInfo->get_attributes().insert(pair<int , AttributeInfo*>(1, lineNumberTable));

    //attribute_name_index
    fread(&lineNumberTable_u2,sizeof(short),1,fw);
    lineNumberTable_u2 = _dataTranslate->smallToBigEndU2(lineNumberTable_u2);
    lineNumberTable->set_attrNameIndex((int*)attribute);

    // attr len
    fread(&lineNumberTable_u4,sizeof(short),1,fw);
    lineNumberTable_u4 = _dataTranslate->smallToBigEndU2(lineNumberTable_u4);
    lineNumberTable->set_attrLength((int*)lineNumberTable_u4);

    // table length
    fread(&lineNumberTable_u2,sizeof(short),1,fw);
    lineNumberTable_u2 = _dataTranslate->smallToBigEndU2(lineNumberTable_u2);
    lineNumberTable->set_tableLength( (int*)lineNumberTable_u2 );

    lineNumberTable->initTable();

    printf(" \t\t\t lineNumberTable : attr_name_index %d attr_len %d table_length %d \n" ,
           attribute, lineNumberTable->get_attrLength() , lineNumberTable->get_tableLength() );

    if((long)lineNumberTable->get_tableLength() > 0 ){
       for( int j = 0 ;j <(long)lineNumberTable->get_tableLength(); j++ ){
           Item* i = new Item;

           //start_PC  u2
           fread(&lineNumberTable_u2,sizeof(short),1,fw);
           lineNumberTable_u2 = _dataTranslate->smallToBigEndU2(lineNumberTable_u2);
           i->setStartPc((short*)lineNumberTable_u2);

           //line_number u2
           fread(&lineNumberTable_u2,sizeof(short),1,fw);
           lineNumberTable_u2 = _dataTranslate->smallToBigEndU2(lineNumberTable_u2);
           i->setLineNumber( (short*)lineNumberTable_u2 );

           printf(" \t\t\t\t 第个 %d 属性 start_PC %d line_number %d \n" , j+1 , i->getStartPc() , i->getLineNumber() );

           lineNumberTable->get_Item()[j] = *i ;
       }
    }

};

//解析属性
void ClassFileParser::parseFile( InstanceKlass* in , FILE* fw ){
    printf(" 开始解析类属性 \n");

    short file_Common_u2;

    list<FieldInfo*> value;

    ConstantPool* cp =  in->get_constantPool();

    for( int i = 0 ;i < in->getfileLength() ; i++ ){

        FieldInfo* fi = new FieldInfo;


        //access_flag; 属性权限
        fread(&file_Common_u2,sizeof(short),1,fw);
        file_Common_u2 = _dataTranslate->smallToBigEndU2(file_Common_u2);
        fi->setaccessFlag(file_Common_u2);

        //name_index 名字下标
        fread(&file_Common_u2,sizeof(short),1,fw);
        file_Common_u2 = _dataTranslate->smallToBigEndU2(file_Common_u2);
        fi->setnameIndex(file_Common_u2);


        //descriptor_index
        fread(&file_Common_u2,sizeof(short),1,fw);
        file_Common_u2 = _dataTranslate->smallToBigEndU2(file_Common_u2);
        fi->setdescriptorIndex(file_Common_u2);


        //attribute_count
        fread(&file_Common_u2,sizeof(short),1,fw);
        file_Common_u2 = _dataTranslate->smallToBigEndU2(file_Common_u2);
        fi->setattributeCount(file_Common_u2);

        if( fi->getattributeCount()>0 ){
            printf(" 属性的 attrubuteCount not 0 \n");
            exit(-1);
        }
        value.push_back(fi);
        //attribute_info attributes[attribute_count]

        printf(" \t 第 %d 个 属性 access flag 为%d  name Index :%d trueName %s  descriptor Index: %d   attribute count %d  \n" , i +1 , fi->getaccessFlag() , fi->getnameIndex() , cp->get_item(fi->getnameIndex()) , fi->getdescriptorIndex() , fi->getattributeCount() );

    }

    in->setFieldInfo(value);

};



void ClassFileParser::parseInterface(InstanceKlass* in , FILE* fw){
    short interfaceCommon_u2;
    ConstantPool* cp = in->get_constantPool();

    list<InterfaceInfo*> b ;

    for( int i = 0 ; i < in->getinterfaceLength() ; i++ ){
        //得到接口名字下标
        fread(&interfaceCommon_u2,sizeof(short),1,fw);
        interfaceCommon_u2 = _dataTranslate ->smallToBigEndU2(interfaceCommon_u2) ;
        //得到类名
        long l = cp->getClassName(interfaceCommon_u2);
        printf(" 第 %d 个 接口 名字为:%s \n" , i+1 , l );
        InterfaceInfo* iif = new InterfaceInfo(interfaceCommon_u2,(long*)l);
        b.push_back(iif);
    };
    in->setInterfaceInfo(b);


};

//解析常量池
void ClassFileParser::parseConstantPool( InstanceKlass* in , FILE* fw ){

    printf(" 开始解析常量池 \n");

    ConstantPool* cp = in->get_constantPool();

    short constantPoolLength = in->get_constantPool()->get_length();

    printf(" 得到常量池大小 %d \n" , constantPoolLength );


    unsigned short short_u2;
    unsigned char char_u1;
    unsigned int int_u4;
    unsigned long long_u8;
    float  float_u4;
    double double_u8;
    char* dynamic;
    short cci_u2;
    short cni_u2;

    for( int i = 1 ; i < constantPoolLength + 1 ; i++ ){

          unsigned char tag;

          fread(&tag,sizeof(tag),1,fw);


//          printf(" tag %d \n" , tag );
          if( tag == cp->JVM_CONSTANT_Utf8 ){

              fread(&short_u2,sizeof(short ),1,fw);

              short_u2 = _dataTranslate ->smallToBigEndU2(short_u2);

              dynamic = new char[short_u2 + 1 ];

              fread(dynamic, short_u2 * sizeof(char),1,fw);

              dynamic[short_u2] = '\0';

              cp->add_item( i , tag , dynamic );

              printf(" 第 %d 个 类型为UTF-8 值为 %s  \n" , i , dynamic );

          }else if( tag == cp->JVM_CONSTANT_Integer ){
              //程序未做处理
              printf("程序未做处理");
          }else if( tag == cp->JVM_COMSTANT_Float ){

              fread(&float_u4,sizeof(float),1,fw);
              //大小端转换
              float_u4 = _dataTranslate->floatb2l(float_u4);
              //floatz转long 存储 老子 代码没了!!!! 日 混账ubuntu 我爱你
              long_u8 = _dataTranslate ->floatToLong(float_u4);
              cp->add_item(i,tag,long_u8);

              printf(" 第 %d 个 类型为 FLOAT 值为:%f \n" , i , float_u4 );

          }else if( tag == cp->JVM_CONSTANT_Long ){

              fread(&long_u8 , sizeof(long) , 1 , fw );
              //long类型大小端转换
              long_u8 = _dataTranslate ->smallToLong(long_u8);
              //将long存储进去
              cp->add_item(i,tag,long_u8);
              printf( " 第 %d 个 类型为LONG 值为:%d  \n" , i , cp->get_item(i) );
              i++;
              cp->add_item(i,tag,long_u8);
              printf(" 第 %d 个 类型为Long 值为:%f \n" , i , _dataTranslate->longToDouble(long_u8) );
          }else if( tag == cp->JVM_CONSTANT_Double ){

              fread(&double_u8,sizeof(double),1,fw);
              //double大小端转换
              double_u8 = _dataTranslate->doubleb2l(double_u8);
              //double转换为long进行存储
              long_u8 = _dataTranslate ->doubleToLong(double_u8);
              cp->add_item(i,tag,long_u8);
              //得到long类型转换为原来的Double类型
              long_u8 = cp->get_item(i);
              printf(" 第 %d 个 类型为DOUBLE 值为:%f \n" , i , _dataTranslate->longToDouble(long_u8) );
              i++;
              cp->add_item(i,tag,long_u8);
              printf(" 第 %d 个 类型为DOUBLE 值为:%f \n" , i , _dataTranslate->longToDouble(long_u8) );
          }else if( tag == cp->JVM_CONSTANT_Class ){

              fread(&short_u2,sizeof(short),1,fw);
              //short大小端转换
              short_u2 = _dataTranslate->smallToBigEndU2(short_u2);

              cp->add_item(i,tag,short_u2);

              printf(" 第 %d 个 类型为Class 值对应下标为:%d \n" , i , cp->get_item(i) );



          }else if( tag == cp->JVM_CONSTANT_String ){

              // u1 u2
              fread(&short_u2,sizeof(short),1,fw);
              //short大小端转换
              short_u2 = _dataTranslate->smallToBigEndU2(short_u2);
              cp->add_item(i,tag,short_u2);
              printf(" 第 %d 个 类型为String 值对应下标为:%d \n" , i , cp->get_item(i) );

          }else if( tag == cp->JVM_CONSTANT_Fielref ){

              //CONSTANT_CLASS_INFO索引
              fread(&cci_u2,sizeof(cci_u2),1,fw);
              //CONSTANT_NameAndTYpe_info
              fread(&cni_u2,sizeof(cni_u2),1,fw);
              cci_u2 = _dataTranslate->smallToBigEndU2(cci_u2);
              cni_u2 = _dataTranslate->smallToBigEndU2(cni_u2);
              //用int类型来接收他们新的值
              int ir = cci_u2 << 16 | cni_u2;
              cp->add_item(i,tag,ir,11);

              short ss =  cp->get_item(i) >> 16;
              short sss =  cp->get_item(i) << 16 >> 16;


              printf(" 第 %d 个类型为Fielref CONSTANT_CLASS_INFO 索引:%d CONSTANT_NameAndType_INFO 下标为:%d \n" , i , (short)(cp->get_item(i) >> 16) , (short )(cp->get_item(i) << 16 >> 16) );

          }else if( tag == cp->JVM_CONSTANT_Methodref ){

              //CONSTANT_CLASS_INFO索引项
              fread(&cci_u2, sizeof(short) , 1 , fw );

              //CONSTANT_NameAndType 的索引项
              fread(&cni_u2, sizeof(short) , 1 , fw );
              cci_u2 = _dataTranslate->smallToBigEndU2(cci_u2);
              cni_u2 = _dataTranslate->smallToBigEndU2(cni_u2);
              int ir = cci_u2 << 16 | cni_u2;
              cp->add_item(i,tag,ir,11);
              printf(" 第 %d 个类型为JVM_CONSTANT_Methodref 指向声明方法类的描述符索引下标为CONSTANT_Class_INFO: %d 指向名称及类型描述符 CONSTANT_NameAndType_INFO索引项: %d \n" , i , (short)(cp->get_item(i) >> 16 )  ,(short)(cp->get_item(i) << 16 >> 16) );
          }else if( tag == cp->JVM_CONSTANT_InterfaceMethodref ){
              //CONSTANT_CLASS_INFO索引项
              fread(&cci_u2, sizeof(short) , 1 , fw );

              //CONSTANT_NameAndType 的索引项
              fread(&cni_u2, sizeof(short) , 1 , fw );
              cci_u2 = _dataTranslate->smallToBigEndU2(cci_u2);
              cni_u2 = _dataTranslate->smallToBigEndU2(cni_u2);
              int ir = cci_u2 << 16 | cni_u2;
              cp->add_item(i,tag,ir,11);
              printf(" 第 %d 个类型为JVM_CONSTANT_InterfaceMethodref  指向声明方法的接口描述符CONSTANT_CLass_Info索引项: %d 指向名称及类型描述符 CONSTANT_NameAndType_INFO 下标为:%d \n" , i , (short)(cp->get_item(i) >> 16 ) ,(short)(cp->get_item(i) << 16 >> 16) );

          }else if( tag == cp->JVM_CONSTANT_NameAndType ){
              //CONSTANT_CLASS_INFO索引项
              fread(&cci_u2, sizeof(short) , 1 , fw );

              //CONSTANT_NameAndType 的索引项
              fread(&cni_u2, sizeof(short) , 1 , fw );
              cci_u2 = _dataTranslate->smallToBigEndU2(cci_u2);
              cni_u2 = _dataTranslate->smallToBigEndU2(cni_u2);
              int ir = cci_u2 << 16 | cni_u2;
              cp->add_item(i,tag,ir,11);
              printf(" 第 %d 个类型为CONSTANT_NameAndType 指向改字段或方法名常量项目索引%d  指向改字段或方法描述符常量项的索引:%d \n" , i , (short)(cp->get_item(i) >> 16) ,(short)(cp->get_item(i) << 16 >> 16) );

          };







    }



};





